﻿using System;
using Icms.Core;
using Icms.Core.Repository;
using Icms.Core.Utils;
using Omu.ValueInjecter;

namespace Icms.WebUI.Builder
{
    public class Mapper<TEntity, TInput> : IMapper<TEntity, TInput>
        where TEntity : class, new()
        where TInput : new()
    {
        private readonly IReadRepo<TEntity> repo;

        public Mapper(IReadRepo<TEntity> repo)
        {
            this.repo = repo;
        }

        public TInput MapToInput(TEntity e)
        {
            var input = new TInput();
            input.InjectFrom(e)
                .InjectFrom<EntitiesToGuids>(e)
                .InjectFrom<NormalToNullables>(e)
                .InjectFrom<ByteArrayToString>(e);

            MakeInput(e, ref input);
            return input;
        }

        protected virtual void MakeInput(TEntity entity, ref TInput input)
        {
        }

        public TEntity MapToEntity(TInput o, Guid? id)
        {
            var e = id.HasValue ? repo.Get(id.Value) : new TEntity();
            if (e == null)
                throw new IcmsException("this entity doesn't exist anymore");

            e.InjectFrom(o)
               .InjectFrom<NullGuidToEntity>(o)
               .InjectFrom<GuidsToEntities>(o)
               .InjectFrom<NullablesToNormal>(o)
               .InjectFrom<StringToByteArray>(o);
            MakeEntity(ref e, o);
            return e;
        }

        protected virtual void MakeEntity(ref TEntity entity, TInput input)
        {
        }

        public TInput RemapInput(TInput createInput, Guid? id)
        {
            return MapToInput(MapToEntity(createInput, id));
        }
    }
}